package com.ikingtech.platform.service.oidc.endpoint;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.platform.service.oidc.client.entity.OidcClientDO;
import com.ikingtech.platform.service.oidc.client.entity.OidcClientRedirectUriDO;
import com.ikingtech.platform.service.oidc.client.service.OidcClientRedirectUriRepository;
import com.ikingtech.platform.service.oidc.client.service.OidcClientRepository;
import com.ikingtech.platform.service.oidc.exception.UnauthorizedClientException;
import com.ikingtech.platform.service.oidc.web.OidcAuthorizationRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.util.MultiValueMap;

import java.util.List;

/**
 * @author tie yan
 */
@RequiredArgsConstructor
public abstract class AbstractOidcEndpoint {

    private final OidcClientRepository clientRepo;

    private final OidcClientRedirectUriRepository clientRedirectUriRepo;

    protected void authenticateClient(OidcAuthorizationRequest authorizationRequest) {
        OidcClientDO client = this.clientRepo.getById(authorizationRequest.getClientId());
        if (null == client) {
            throw new UnauthorizedClientException();
        }
        if (Tools.Str.equals(client.getSecret(), client.getSecret())) {
            throw new UnauthorizedClientException();
        }
        List<String> redirectUris = this.clientRedirectUriRepo.listObjs(Wrappers.<OidcClientRedirectUriDO>lambdaQuery().select(OidcClientRedirectUriDO::getRedirectUri).eq(OidcClientRedirectUriDO::getClientId, authorizationRequest.getClientId()));
        if (Tools.Coll.isBlank(redirectUris) || !redirectUris.contains(authorizationRequest.getRedirectUri())) {
            throw new UnauthorizedClientException();
        }
    }

    protected OidcAuthorizationRequest convertRequest(MultiValueMap<String, String> paramMap) {
        OidcAuthorizationRequest request = new OidcAuthorizationRequest();
        String clientId = paramMap.getFirst(OidcAuthorizationRequest.AuthenticationRequestFieldName.CLIENT_ID);
        if (Tools.Str.isBlank(clientId)) {
            throw new UnauthorizedClientException();
        }
        request.setClientId(clientId);
        String clientSecret = paramMap.getFirst(OidcAuthorizationRequest.AuthenticationRequestFieldName.CLIENT_SECRET);
        if (Tools.Str.isBlank(clientSecret)) {
            throw new UnauthorizedClientException();
        }
        request.setClientSecret(clientSecret);

        String redirectUri = paramMap.getFirst(OidcAuthorizationRequest.AuthenticationRequestFieldName.REDIRECT_URI);
        if (Tools.Str.isBlank(redirectUri)) {
            throw new UnauthorizedClientException();
        }
        request.setRedirectUri(redirectUri);
        return request;
    }
}
